﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace XGame.Content
{

    /// <summary>
    /// The basic manager class that is responsible for a single type of content.
    /// </summary>
    /// <typeparam name="T">The content type to keep track of.</typeparam>
    public class Manager<T> : Dictionary<String, T>
        where T : class
    {

        private ContentManager iManager = null;
        private String iRootPath = String.Empty;

        /// <summary>
        /// Creates a new instance of the Manager class with the given
        /// root path and a reference to the content manager object of the game
        /// </summary>
        /// <param name="aRootPath">The root path for the content</param>
        /// <param name="aManager">A reference to the ContentManager object to load content from</param>
        public Manager(String aRootPath, ContentManager aManager)
        {
            iManager = aManager;
            iRootPath = aRootPath;
        }

        /// <summary>
        /// Attempts to load content from the ContentManager object.
        /// </summary>
        /// <param name="aContentName">The name of the content to load, minus any extensions</param>
        /// <returns>A boolean flag that indicates whether or not the content was successfully loaded.
        /// If the content exists already internally, this method will return true</returns>
        public Boolean Load(String aContentName)
        {

            // Declare the return value
            Boolean bReturnValue = true;

            // Check to see if this content exists already
            if(!Exists(aContentName))
            {
                T oLoadedContent = iManager.Load<T>(aContentName);
                if (oLoadedContent == null)
                    bReturnValue = false;
                else
                    this.Add(aContentName, oLoadedContent);
            }

            // All done, give the value back
            return bReturnValue;

        }

        /// <summary>
        /// Checks to see if a specified name has been loaded from file.
        /// </summary>
        /// <param name="aContentName">The name of the content to check</param>
        /// <returns>A boolean flag that indicates whether or not the content exists and is loaded</returns>
        public Boolean Exists(String aContentName)
        {
            return this.ContainsKey(aContentName);
        }

        /// <summary>
        /// Retrieves the specified content object from the Manager
        /// </summary>
        /// <typeparam name="T">The type of content to return</typeparam>
        /// <param name="aContentName">The name of the content to return</param>
        /// <returns>The content of type <typeparamref name="T"/>.</returns>
        /// <exception cref="System.ArgumentException">Thrown when the content isn't loaded</exception>
        public T Get(String aContentName)
        {
            if (!Exists(aContentName)) throw new ArgumentException("aContentName");
            return this[aContentName];
        }

    }

}
